package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"net/smtp"
	"reflect"
	"regexp"
	"strings"
)

// FeiShu 告警信息推送至飞书
func FeiShu(formatMsg string) {
	key, _ := GetConfig("FeiShu", "key")
	group, _ := GetConfig("FeiShu", "group")

	headers := map[string]string{"Content-Type": "application/json;charset=utf-8"}
	api := "https://open.FeiShu.cn/open-apis/bot/v2/hook/" + strings.Split(group, ",")[0]

	// 格式化@
	pattern := regexp.MustCompile(`ou_([a-z0-9]+)$([^)]+)$`)
	matches := pattern.FindAllStringSubmatch(group, -1)
	atS := ""
	for _, match := range matches {
		atS += fmt.Sprintf("<at id=ou_%s>%s</at>", match[1], match[2])
	}

	body := map[string]interface{}{
		"msg_type": "interactive",
		"is_short": false,
		"card": map[string][]map[string]string{
			"elements": {{
				"tag":     "markdown",
				"content": key + formatMsg + atS,
			}},
		},
	}

	jsonBody, _ := json.Marshal(body)
	resp, err := http.Post(api, headers["Content-Type"], bytes.NewBuffer(jsonBody))
	if err != nil {
		log.Infof("告警信息推送失败: %v", err)
		return
	}
	defer func(Body io.ReadCloser) {
		err := Body.Close()
		if err != nil {
			log.Error(err)
		}
	}(resp.Body)
	response, _ := io.ReadAll(resp.Body)
	log.Infof("告警信息推送: %s", response)
}

func DingDing(data AlertData) {
	groupInfo, err := GetConfig("DingDing", "group1")
	if err != nil {
		log.Fatalf("Error getting group info from config: %v", err)
	}

	token := strings.Split(groupInfo, ",")[0]

	headers := map[string]string{"Content-Type": "application/json;charset=utf-8"}
	api := fmt.Sprintf("https://oapi.dingtalk.com/robot/send?access_token=%s", token)

	val := reflect.ValueOf(data)
	typ := val.Type()

	template := ""
	for i := 0; i < typ.NumField(); i++ {
		field := typ.Field(i)
		tag := field.Tag.Get("yaml")
		if tag == "" {
			tag = field.Name
		}
		template += fmt.Sprintf("**%s:** %%v  \n", tag)
	}

	args := make([]interface{}, val.NumField())
	for i := 0; i < val.NumField(); i++ {
		args[i] = val.Field(i).Interface()
	}
	alertMessage := fmt.Sprintf(template, args...)

	body := map[string]interface{}{
		"msgtype": "markdown",
		"markdown": map[string]string{
			"title": "ECS异常-监控报警",
			"text":  alertMessage,
		},
		"at": map[string][]string{
			"atMobiles": {},
			"atUserIds": {},
			"isAtAll":   {"false"},
		},
	}

	jsonBody, err := json.Marshal(body)
	if err != nil {
		log.Errorf("Failed to marshal request body: %v", err)
		return
	}

	resp, err := http.Post(api, headers["Content-Type"], bytes.NewBuffer(jsonBody))
	if err != nil {
		log.Errorf("告警推送失败: %v", err)
		return
	}
	defer func(Body io.ReadCloser) {
		err := Body.Close()
		if err != nil {
			log.Error(err)
		}
	}(resp.Body)

	pushState, err := io.ReadAll(resp.Body)
	if err != nil {
		log.Errorf("读取pushState失败\n: %v", err)
		return
	}

	var response map[string]interface{}
	err = json.Unmarshal(pushState, &response)
	if err != nil {
		log.Errorf("解散reponse失败: %v", err)
		return
	}

	if msg, ok := response["errmsg"].(string); ok && msg == "ok" {
		log.Info("告警推送成功")
	} else {
		log.Errorf("告警推送失败: %s", pushState)
	}
}

// Email 将告警信息推送至邮箱
func Email(formatMsg string) {
	user, _ := GetConfig("email", "user")
	password, _ := GetConfig("email", "password")
	host, _ := GetConfig("email", "host")
	port, _ := GetConfig("email", "port")
	addressee, _ := GetConfig("email", "addressee")
	subject, _ := GetConfig("email", "subject")
	//sender, _ := GetConfig("email", "sender")

	//passwordDecrypted, err := SalsaCrypt(password, false)
	// 配置文件添加明文，启动后自动加密
	msg := []byte(fmt.Sprintf("To: %s\r\n"+
		"Subject: %s\r\n"+
		"MIME-Version: 1.0;\r\n"+
		"Content-Type: text/plain; charset=UTF-8\r\n\r\n"+
		"%s", addressee, subject, formatMsg))

	err := smtp.SendMail(host+":"+port, smtp.PlainAuth("", user, password, host), user, strings.Split(addressee, ","), msg)
	if err != nil {
		log.Error(err)
	}
	if err != nil {
		log.Errorf("邮件发送失败: %v", err)
	} else {
		log.Info("邮件已发送!")
	}
}
